﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

using Aliphant.Common.Helper;
using Aliphant.Mvvm.XEvent.Events;
using Aliphant.Mvvm.XEvent.UI;
using Aliphant.UI;
using Aliphant.Widget.JS.Models;
using Aliphant.Widget.JS.Utility;
using Aliphant.Widget.JS.Views;

namespace Aliphant.Widget.JS.ViewModels
{
    public class MainPageViewModel : BindableBase
    {
        private WindowEvent _windowEvent;
        private Dictionary<string, UI.Widget> widgets = new Dictionary<string, UI.Widget>();
        public ObservableCollection<WidgetConfig> WidgetCollections { get; private set; } = new ObservableCollection<WidgetConfig>();


        public MainPageViewModel()
        {
            _windowEvent = WidgetCenterModule.EventAgent.GetEvent<WindowEvent>();
            _windowEvent.Subscribe(Release, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Close && p.EventId == EventIds.Release);

            Load();
        }

        public void Load()
        {
            WidgetCollections.Clear();

            string widgetPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Widgets");
            if (!Directory.Exists(widgetPath))
            {
                Directory.CreateDirectory(widgetPath);
                return;
            }

            string[] dirs = Directory.GetDirectories(widgetPath);
            foreach (var dir in dirs)
            {
                string filePath = Path.Combine(dir, "widget.json");
                if (!File.Exists(filePath))
                {
                    continue;
                }

                JsonHelper.ReadJson<WidgetConfig>(filePath, out WidgetConfig? config);

                if (config != null)
                {
                    WidgetCollections.Add(config);
                }
            }
        }

        public ICommand RefreshCommand
        {
            get => new UICommand<object>(obj =>
            {
                Load();
            });
        }

        public ICommand OpenWidgetWindowCommand
        {
            get => new UICommand<WidgetConfig>(async cfg =>
            {
                if (cfg == null)
                {
                    return;
                }

                if (CanShowWidget(cfg.Id))
                {
                    return;
                }

                string pRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Widgets", cfg.Id);
                string pView = Path.Combine(pRoot, cfg.View);
                string pScript = Path.Combine(pRoot, cfg.Script);

                if (!File.Exists(pScript) || !File.Exists(pScript))
                {
                    MessageBox.Show($"小组件{cfg.Name}不存在");
                }

                try
                {
                    var page = PageHelper.LoadContentXaml(pView);
                    if (page == null)
                    {
                        return;
                    }

                    if (!(page is IWidget content))
                    {
                        return;
                    }

                    await PageHelper.LoadJavaScript(content, pScript);

                    Aliphant.UI.Widget widget = new UI.Widget(content, false, false);
                    widget.Show();

                    if (cfg.Single)
                    {
                        this.widgets.Add(Guid.NewGuid().ToString(), widget);
                    }
                    else
                    {
                        this.widgets.Add(cfg.Id, widget);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            });
        }

        private bool CanShowWidget(string key)
        {
            if (this.widgets.ContainsKey(key))
            {
                var wb = this.widgets[key];
                if (wb != null && !wb.IsClosed)
                {
                    wb.Show();
                    return true;
                }
                this.widgets.Remove(key);
            }
            return false;
        }

        private void Release(WindowEvent @event)
        {
            foreach (var widget in this.widgets.Values)
            {
                widget.Close();
            }
        }

    }
}
